package com.eb.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.util.Enumeration;

import org.apache.log4j.Logger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

/**
 * 文件工具类
 * @author Administrator
 *
 */
public class FileUtil {
	
	private static Logger logger = Logger.getLogger(FileUtil.class);
	
	/**
	 * 文件或文件夹 ---> 文件夹
	 * @param newDicPath : 目标文件夹
	 * @param oldPath： 原文件或文件夹
	 * @return
	 */
	public static Boolean copy(String newDirPath,String oldPath){
		Boolean boo = false;
		try{
			File file = new File(oldPath);
			File newDic = new File(newDirPath);
			if(!newDic.exists())
				newDic.mkdirs();
			if(file.isFile()){
				String newFilePath = newDirPath+File.separator+file.getName();
				copyFile(newFilePath, oldPath);
			}else if(file.isDirectory()){
				copyDir(newDirPath, oldPath);
			}
			boo = true;
		}catch(Exception e){
			logger.error("copy error", e);
		}
		return boo;
	}
	
	/**
	 * 文件--->文件   的复制
	 * @param newPath
	 * @param oldPath
	 * 如果新文件已经存在，则进行覆盖
	 * @return
	 */
	public static Boolean copyFile(String newFilePath,String oldFilePath){
		Boolean boo = false;
		FileInputStream fi = null;
		FileOutputStream fo = null;
		FileChannel in = null;
		FileChannel out = null;
		try{
			fi = new FileInputStream(new File(oldFilePath));
			fo = new FileOutputStream(new File(newFilePath));
			in = fi.getChannel();//得到对应的文件通道
			out = fo.getChannel();//得到对应的文件通道
			in.transferTo(0, in.size(), out);//连接两个通道，并且从in通道读取，然后写入out通道
			boo = true;
		}catch(Exception t){
			logger.error("copyFile error", t);
		}finally{
			closeIo(fi);
			closeIo(in);
			closeIo(fo);
			closeIo(out);
		}
		return boo;
	}
	
	/**
	 * 文件夹--->文件夹   的复制
	 * @param newPath
	 * @param oldPath
	 * 如果新文件已经存在，则进行覆盖
	 * @return
	 */
	public static Boolean copyDir(String newDirPath,String oldDirPath){
		Boolean boo = false;
		try{
			File newDic = new File(newDirPath);
			if(!newDic.exists())
				newDic.mkdirs();
			File oldDic = new File(oldDirPath);
			File [] files = oldDic.listFiles();
			for(File file : files){
				if(file.isFile()){
					String newFilePath = newDirPath+File.separator+file.getName();
					copyFile(newFilePath, file.getAbsolutePath());
				}else if(file.isDirectory()){
					String dir1=oldDirPath+File.separator+file.getName();
					String dir2=newDirPath+File.separator+file.getName();
					copyDir(dir2, dir1);
				}
			}
			boo = true;
		}catch(Exception t){
			logger.error("copyDir", t);
		}
		return boo;
	}
	
	/**
	 * 文件或文件夹的移动
	 * @param newPath
	 * @param oldPath
	 * @return
	 */
	public static Boolean move(String newDirPath,String oldPath){
		Boolean boo = false;
		try{
			File file = new File(oldPath);
			File dir = new File(newDirPath);
			if(!dir.exists())
				dir.mkdirs();
			boo = file.renameTo(new File(dir, file.getName()));
		}catch(Exception t){
			logger.error("deleteDir", t);
		}
		return boo;
	}
	
	/**
	 * 文件的删除
	 * @param filePath
	 * @return
	 */
	public static Boolean deleteFile(String filePath){
		Boolean boo = false;
		try{
			File file = new File(filePath);
			boo =file.delete();
		}catch(Exception t){
			logger.error("deleteDir", t);
		}
		return boo;
	}
	
	/**
	 * 文件夹的删除
	 * @param filePath
	 * @return
	 */
	public static Boolean deleteDir(String dirPath){
		Boolean boo = false;
		try{
			File dic = new File(dirPath);
			File [] files = dic.listFiles();
			for(File file : files){
				if(!file.exists())
					continue;
				if(file.isFile()){
					file.delete();
				}else if(file.isDirectory()){
					deleteDir(file.getAbsolutePath());
				}
			}
			dic.delete();
			boo = true;
		}catch(Exception t){
			logger.error("deleteDic", t);
		}
		return boo;
	}
	
	/**
	 * 判断是否文件夹
	 * @return
	 */
	public static Boolean isDir(String filePath){
		Boolean boo = false;
		try{
			File file = new File(filePath);
			boo = file.isDirectory();
		}catch(Exception t){
			logger.error("isDic error", t);
		}
		return boo;
	}
	
	/**
	 * 判断是否文件
	 * @return
	 */
	public static Boolean isFile(String filePath){
		Boolean boo = false;
		try{
			File file = new File(filePath);
			boo = file.isFile();
		}catch(Exception t){
			logger.error("isFIle error", t);
		}
		return boo;
	}
	
	/**
	 * 判断是否存在
	 * @return
	 */
	public static Boolean isExists(String filePath){
		Boolean boo = false;
		try{
			File file = new File(filePath);
			boo = file.exists();
		}catch(Exception t){
			logger.error("isExists error", t);
		}
		return boo;
	}
	
	/**
	 * 读取文件内容(以字符为单位)
	 * @return
	 */
	@SuppressWarnings("unused")
	public static String readFile(String filePath){
		StringBuffer sb = new StringBuffer();
		BufferedReader reader = null;
		try{
			File file = new File(filePath);
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            int line = 1;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                // 显示行号
                if("".equals(tempString))
                	sb.append("\n");
                sb.append(tempString);
                line++;
            }
            reader.close();
		}catch(Exception t){
			logger.error("isExists error", t);
		}
		return sb.toString();
	}
	
	/**
	 * 文件追加内容
	 * @return
	 */
	public static Boolean appendFile(String filePath){
		return false;
	}
	
	/**
	 * 替换文件内容
	 * @return
	 */
	public static Boolean relpaceFile(String filePath,String oldStr,String newStr){
		return false;
	}
	
	/*
	 * 压缩文件所需ant.jar
	 * <dependency>
	 * 		<groupId>org.apache.ant</groupId>
	 *  	<artifactId>ant</artifactId>
	 *  	<version>1.8.2</version>
	 * </dependency>
	 * 
	 */
	
	/**
	 * 压缩文件夹
	 * 借助于第三方jar
	 * zip("E:/d/a.zip", "E:/b");
	 * zip路径自动创建
	 */
	public static Boolean zipDir(String zipPath,String dirPath){
		Boolean boo = false;
		try {
			File file = new File(dirPath); 
			File zipFile = new File(zipPath);
			Project prj = new Project();    
			Zip zip = new Zip();    
			zip.setProject(prj);    
			zip.setDestFile(zipFile);    
			FileSet fileSet = new FileSet();    
			fileSet.setProject(prj);    
			fileSet.setDir(file);    
			zip.addFileset(fileSet);    
			zip.execute();
			boo = true;
		} catch (BuildException e) {
			logger.error("zip error", e);
		}   
		return boo;
	}
	
	/**
	 * 压缩单个文件
	 * @param zipPath
	 * @param filePath
	 * zip路径不会自动创建,需手动创建 E:/d/文件夹
	 * zipFile("E:/d/a.zip"", "E:/11.txt");
	 */
	public static Boolean zipFile(String zipPath,String filePath){
		Boolean boo = false;
		try {
			File file = new File(filePath);
			int length = (int) file.length();
			byte[] b = new byte[length];
			InputStream in = new FileInputStream(file);
			in.read(b);  
            closeIo(in);
            ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(new File(zipPath)));
            zout.setLevel(9);  
            ZipEntry zipEntry = new ZipEntry(file.getName());  
            zout.putNextEntry(zipEntry);  
            zout.write(b);  
            zout.finish();  
            closeIo(zout);
			boo = true;
		} catch (Exception e) {
			logger.error("zip error", e);
		}
		return boo;
	}
	
	
	/**
	 * 解压文件
	 * zipPath: 源压缩包路径
	 * unzipDir ： 目标文件夹
	 * @return
	 */
	@SuppressWarnings({ "resource", "rawtypes" })
	public static Boolean unzip(String zipPath,String unzipDir){
		Boolean boo = false;
		try {
			unzipDir = unzipDir.endsWith("\\") ? unzipDir : unzipDir + "\\";
			byte b[] = new byte[1024];
			int length;
			ZipFile zipFile = new ZipFile(new File(zipPath));
			Enumeration enumeration = zipFile.getEntries();
			ZipEntry zipEntry = null;
			while (enumeration.hasMoreElements()) { 
				zipEntry = (ZipEntry) enumeration.nextElement();
				File loadFile = new File(unzipDir + zipEntry.getName()); 
				if (zipEntry.isDirectory()) {
					loadFile.mkdirs();
				}else{
					if (!loadFile.getParentFile().exists()){  
						loadFile.getParentFile().mkdirs();
					}
					OutputStream outputStream = new FileOutputStream(loadFile);
					InputStream inputStream = zipFile.getInputStream(zipEntry);
					while ((length = inputStream.read(b)) > 0){
						 outputStream.write(b, 0, length);
					}
				}
			}
			boo = true;
		} catch (Exception e) {
			logger.error("unzip error", e);
		} 
		return boo;
	}
	
	/**
	 * 	功能:获取文件扩展名
	 *	王浩  @2015-7-26
	 */
	public static String getExtensionName(String fileName) {  
		int dot = fileName.lastIndexOf('.');
		 if ((dot >-1) && (dot < (fileName.length() - 1))){
			 return fileName.substring(dot + 1);
		 }
		 return "";
	}
	
	
	/**
	 * 关闭流
	 * @param in
	 */
	public static void closeIo(InputStream in){
		try {
			if(in != null)
				in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 关闭流
	 * @param in
	 */
	public static void closeIo(OutputStream out){
		try {
			if(out != null)
				out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 关闭流
	 * @param in
	 */
	public static void closeIo(FileChannel fc){
		try {
			if(fc != null)
				fc.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		Boolean aa = unzip("E:/a.zip", "E:/a");
		System.out.println(aa);
	}
	
	
}
